#    pythonequations is a collection of equations expressed as Python classes
#    Copyright (C) 2008 James R. Phillips
#    2548 Vera Cruz Drive
#    Birmingham, AL 35235 USA
#    email: zunzun@zunzun.com
#
#    License: BSD-style (see LICENSE.txt in main source directory)
#    Version info: $Id: __init__.py 267 2010-09-25 13:25:43Z zunzun.com $

import pythonequations, pythonequations.EquationBaseClasses, pythonequations.ExtraCodeForEquationBaseClasses
import numpy
numpy.seterr(all = 'raise') # numpy raises warnings, convert to exceptions to trap them


class RomanSurfacePlus3D(pythonequations.EquationBaseClasses.Equation3D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = False
    RequiresAutoGeneratedInverseForms = False
    _name ="Roman Surface (plus)"
    _HTML = "z = (k(y<sup>2</sup>-x<sup>2</sup>) + (x<sup>2</sup>-y<sup>2</sup>)sqrt(k<sup>2</sup>-x<sup>2</sup>-y<sup>2</sup>)) / (2(x<sup>2</sup>+y<sup>2</sup>))"
    coefficientDesignatorTuple = ("k")
    function_cpp_code = 'temp = ( (coeff[0] * _id[_cwo[1]+i]) + (_id[_cwo[1]+i] * pow( (coeff[0] * coeff[0]) - _id[_cwo[0]+i], 0.5)) ) / (2.0 * _id[_cwo[2]+i]);'

    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_XSQMINUSYSQ(NameOrValueFlag=1), []])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_YSQMINUSXSQ(NameOrValueFlag=1), []])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_XSQPLUSYSQ(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = (k * (y_in * y_in - x_in * x_in) + (x_in * x_in - y_in * y_in) * pow(k * k - x_in * x_in - y_in * y_in, 0.5)) / (2.0 * (x_in * x_in + y_in * y_in));\n"
        return s



class RomanSurfaceMinus3D(pythonequations.EquationBaseClasses.Equation3D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = False
    RequiresAutoGeneratedInverseForms = False
    _name ="Roman Surface (minus)"
    _HTML = "z = (k(y<sup>2</sup>-x<sup>2</sup>) - (x<sup>2</sup>-y<sup>2</sup>)sqrt(k<sup>2</sup>-x<sup>2</sup>-y<sup>2</sup>)) / (2(x<sup>2</sup>+y<sup>2</sup>))"
    coefficientDesignatorTuple = ("k")
    function_cpp_code = 'temp = ( (coeff[0] * _id[_cwo[1]+i]) - (_id[_cwo[1]+i] * pow( (coeff[0] * coeff[0]) - _id[_cwo[0]+i], 0.5)) ) / (2.0 * _id[_cwo[2]+i]);'

    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_XSQMINUSYSQ(NameOrValueFlag=1), []])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_YSQMINUSXSQ(NameOrValueFlag=1), []])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_XSQPLUSYSQ(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = (k * (y_in * y_in - x_in * x_in) - (x_in * x_in - y_in * y_in) * pow(k * k - x_in * x_in - y_in * y_in, 0.5)) / (2.0 * (x_in * x_in + y_in * y_in));\n"
        return s



class RomanSurfacePlus_OffsetXY_3D(pythonequations.EquationBaseClasses.Equation3D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = False
    RequiresAutoGeneratedInverseForms = False
    _name ="Roman Surface (plus) Offset XY"
    _HTML = "z = (k((y+b)<sup>2</sup>-(x+a)<sup>2</sup>) + ((x+a)<sup>2</sup>-(y+b)<sup>2</sup>)sqrt(k<sup>2</sup>-(x+a)<sup>2</sup>-(y+b)<sup>2</sup>)) / (2((x+a)<sup>2</sup>+(y+b)<sup>2</sup>))"
    coefficientDesignatorTuple = ("k", "a",  "b")
    function_cpp_code = 'temp_x_sq = temp_x_sq * temp_x_sq;\n'
    function_cpp_code += 'temp_y_sq = _id[_cwo[1]+i] + coeff[2];\n'
    function_cpp_code += 'temp_y_sq = temp_y_sq * temp_y_sq;\n'
    function_cpp_code += 'temp = ( (coeff[0] * (temp_y_sq - temp_x_sq)) + ((temp_x_sq - temp_y_sq) * pow( (coeff[0] * coeff[0]) - temp_x_sq - temp_y_sq, 0.5)) ) / (2.0 * (temp_x_sq + temp_y_sq));'

    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_Y(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = ""
        j = self.coefficientDesignatorTuple # makes coding below easier to read
        s += '\tdouble temp_x_sq = (x_in + ' + j[1] + ') * (x_in + ' + j[1] + ') ;\n' # note the ending space, no "offset form" replacement here
        s += '\tdouble temp_y_sq = (y_in + ' + j[2] + ') * (y_in + ' + j[2] + ') ;\n' # note the ending space, no "offset form" replacement here
        s += "\ttemp = (k * (temp_y_sq - temp_x_sq) + (temp_x_sq - temp_y_sq) * pow(k * k - temp_x_sq - temp_y_sq, 0.5)) / (2.0 * (temp_x_sq + temp_y_sq));\n"
        return s



class RomanSurfaceMinus_OffsetXY_3D(pythonequations.EquationBaseClasses.Equation3D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = False
    RequiresAutoGeneratedInverseForms = False
    _name ="Roman Surface (minus) Offset XY"
    _HTML = "z = (k((y+b)<sup>2</sup>-(x+a)<sup>2</sup>) - ((x+a)<sup>2</sup>-(y+b)<sup>2</sup>)sqrt(k<sup>2</sup>-(x+a)<sup>2</sup>-(y+b)<sup>2</sup>)) / (2((x+a)<sup>2</sup>+(y+b)<sup>2</sup>))"
    coefficientDesignatorTuple = ("k", "a",  "b")
    function_cpp_code = 'temp_x_sq = temp_x_sq * temp_x_sq;\n'
    function_cpp_code += 'temp_y_sq = _id[_cwo[1]+i] + coeff[2];\n'
    function_cpp_code += 'temp_y_sq = temp_y_sq * temp_y_sq;\n'
    function_cpp_code += 'temp = ( (coeff[0] * (temp_y_sq - temp_x_sq)) - ((temp_x_sq - temp_y_sq) * pow( (coeff[0] * coeff[0]) - temp_x_sq - temp_y_sq, 0.5)) ) / (2.0 * (temp_x_sq + temp_y_sq));'

    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_Y(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = ""
        j = self.coefficientDesignatorTuple # makes coding below easier to read
        s += '\tdouble temp_x_sq = (x_in + ' + j[1] + ') * (x_in + ' + j[1] + ') ;\n' # note the ending space, no "offset form" replacement here
        s += '\tdouble temp_y_sq = (y_in + ' + j[2] + ') * (y_in + ' + j[2] + ') ;\n' # note the ending space, no "offset form" replacement here
        s += "\ttemp = (k * (temp_y_sq - temp_x_sq) - (temp_x_sq - temp_y_sq) * pow(k * k - temp_x_sq - temp_y_sq, 0.5)) / (2.0 * (temp_x_sq + temp_y_sq));\n"
        return s



class RomanSurfacePlus_ScaledAndOffsetXY_3D(pythonequations.EquationBaseClasses.Equation3D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = False
    RequiresAutoGeneratedInverseForms = False
    _name ="Roman Surface (plus) Scaled And Offset XY"
    _HTML = "z = (k((cy+d)<sup>2</sup>-(ax+b)<sup>2</sup>) + ((ax+b)<sup>2</sup>-(cy+d)<sup>2</sup>)sqrt(k<sup>2</sup>-(ax+b)<sup>2</sup>-(cy+d)<sup>2</sup>)) / (2((ax+b)<sup>2</sup>+(cy+d)<sup>2</sup>))"
    coefficientDesignatorTuple = ("k", "a",  "b",  "c",  "d")
    function_cpp_code = 'temp_x_sq = temp_x_sq * temp_x_sq;\n'
    function_cpp_code += 'temp_y_sq = coeff[3] * _id[_cwo[1]+i] + coeff[4];\n'
    function_cpp_code += 'temp_y_sq = temp_y_sq * temp_y_sq;\n'
    function_cpp_code += 'temp = ( (coeff[0] * (temp_y_sq - temp_x_sq)) + ((temp_x_sq - temp_y_sq) * pow( (coeff[0] * coeff[0]) - temp_x_sq - temp_y_sq, 0.5)) ) / (2.0 * (temp_x_sq + temp_y_sq));'

    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_Y(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = ""
        j = self.coefficientDesignatorTuple # makes coding below easier to read
        s += '\tdouble temp_x_sq = (' + j[1] + ' * x_in + ' + j[2] + ') * (' + j[1] + ' * x_in + ' + j[2] + ') ;\n' # note the ending space, no "offset form" replacement here
        s += '\tdouble temp_y_sq = (' + j[3] + ' * y_in + ' + j[4] + ') * (' + j[3] + ' * y_in + ' + j[4] + ') ;\n' # note the ending space, no "offset form" replacement here
        s += "\ttemp = (k * (temp_y_sq - temp_x_sq) + (temp_x_sq - temp_y_sq) * pow(k * k - temp_x_sq - temp_y_sq, 0.5)) / (2.0 * (temp_x_sq + temp_y_sq));\n"
        return s



class RomanSurfaceMinus_ScaledAndOffsetXY_3D(pythonequations.EquationBaseClasses.Equation3D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = False
    RequiresAutoGeneratedInverseForms = False
    _name ="Roman Surface (minus) Scaled And Offset XY"
    _HTML = "z = (k((cy+d)<sup>2</sup>-(ax+b)<sup>2</sup>) - ((ax+b)<sup>2</sup>-(cy+d)<sup>2</sup>)sqrt(k<sup>2</sup>-(ax+b)<sup>2</sup>-(cy+d)<sup>2</sup>)) / (2((ax+b)<sup>2</sup>+(cy+d)<sup>2</sup>))"
    coefficientDesignatorTuple = ("k", "a",  "b",  "c",  "d")
    function_cpp_code = 'temp_x_sq = temp_x_sq * temp_x_sq;\n'
    function_cpp_code += 'temp_y_sq = coeff[3] * _id[_cwo[1]+i] + coeff[4];\n'
    function_cpp_code += 'temp_y_sq = temp_y_sq * temp_y_sq;\n'
    function_cpp_code += 'temp = ( (coeff[0] * (temp_y_sq - temp_x_sq)) - ((temp_x_sq - temp_y_sq) * pow( (coeff[0] * coeff[0]) - temp_x_sq - temp_y_sq, 0.5)) ) / (2.0 * (temp_x_sq + temp_y_sq));'

    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_Y(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = ""
        j = self.coefficientDesignatorTuple # makes coding below easier to read
        s += '\tdouble temp_x_sq = (' + j[1] + ' * x_in + ' + j[2] + ') * (' + j[1] + ' * x_in + ' + j[2] + ') ;\n' # note the ending space, no "offset form" replacement here
        s += '\tdouble temp_y_sq = (' + j[3] + ' * y_in + ' + j[4] + ') * (' + j[3] + ' * y_in + ' + j[4] + ') ;\n' # note the ending space, no "offset form" replacement here
        s += "\ttemp = (k * (temp_y_sq - temp_x_sq) - (temp_x_sq - temp_y_sq) * pow(k * k - temp_x_sq - temp_y_sq, 0.5)) / (2.0 * (temp_x_sq + temp_y_sq));\n"
        return s
